// Neo4j查询：找到最大连通子图
// =====================================

// 方法1：使用Cypher原生查询找到连通分量
// 这个查询会找到所有连通分量并返回最大的一个

// 1.1 首先标记所有节点的连通分量ID（使用广度优先搜索）
// 注意：这个查询对于大图可能会很慢
MATCH (n:Node)
WHERE NOT EXISTS(n.component)
WITH collect(n) as nodes
UNWIND range(0, size(nodes)-1) as idx
WITH nodes[idx] as startNode, idx
WHERE NOT EXISTS(startNode.component)
CALL {
    WITH startNode, idx
    MATCH path = (startNode)-[*]-(connected:Node)
    WHERE NOT EXISTS(connected.component)
    WITH collect(DISTINCT connected) as component, idx
    FOREACH (node IN component | SET node.component = idx)
    RETURN size(component) as componentSize, idx
}
RETURN idx as componentId, componentSize
ORDER BY componentSize DESC
LIMIT 1;

// 1.2 获取最大连通分量的节点数
MATCH (n:Node)
WITH n.component as componentId, count(n) as size
ORDER BY size DESC
LIMIT 1
RETURN componentId, size as maxComponentSize;

// 1.3 获取最大连通分量的所有节点
MATCH (n:Node)
WITH n.component as componentId, count(n) as size
ORDER BY size DESC
LIMIT 1
MATCH (node:Node {component: componentId})
RETURN node
LIMIT 100;  // 限制返回数量以便可视化

// =====================================
// 方法2：不修改数据的查询方法
// 使用子图投影来找连通分量

// 2.1 找到度数最高的节点作为起点，探索其连通分量
MATCH (start:Node)
WITH start
ORDER BY start.degree DESC
LIMIT 1
CALL {
    WITH start
    MATCH path = (start)-[*]-(connected:Node)
    RETURN count(DISTINCT connected) as connectedCount,
           collect(DISTINCT connected)[0..10] as sampleNodes
}
RETURN start.id as startNode,
       connectedCount as componentSize,
       sampleNodes;

// 2.2 采样方法：从多个高度节点开始，找到最大的连通分量
MATCH (n:Node)
WHERE n.degree > 50
WITH n
ORDER BY n.degree DESC
LIMIT 10
CALL {
    WITH n
    MATCH (n)-[*..3]-(connected:Node)  // 限制深度为3以提高性能
    RETURN n.id as seedNode,
           count(DISTINCT connected) as reachableNodes
}
RETURN seedNode, reachableNodes
ORDER BY reachableNodes DESC
LIMIT 1;

// =====================================
// 方法3：实用的查询 - 找到核心连通子图
// 这个查询找到由高度节点组成的核心连通子图

// 3.1 找到相互连接的高度节点群
MATCH (n1:Node)-[r]-(n2:Node)
WHERE n1.degree > 30 AND n2.degree > 30
WITH n1, count(DISTINCT n2) as connections
WHERE connections > 5
RETURN n1.id, n1.type, n1.degree, connections
ORDER BY connections DESC
LIMIT 20;

// 3.2 可视化核心连通子图
MATCH (n1:Node)
WHERE n1.degree > 50
MATCH path = (n1)-[*..2]-(n2:Node)
WHERE n2.degree > 30
RETURN path
LIMIT 100;

// =====================================
// 方法4：统计连通性信息

// 4.1 检查图的整体连通性
MATCH (n:Node)
WITH count(n) as totalNodes
MATCH (n1:Node)
WHERE n1.degree > 0
WITH totalNodes, count(DISTINCT n1) as connectedNodes
RETURN totalNodes,
       connectedNodes,
       toFloat(connectedNodes)/toFloat(totalNodes) as connectivityRatio;

// 4.2 找到孤立节点（度为0的节点）
MATCH (n:Node)
WHERE n.degree = 0
RETURN n.id, n.type
LIMIT 20;

// 4.3 找到桥接节点（连接多个组件的关键节点）
MATCH (n:Node)
WHERE n.degree > 20
MATCH (n)-[r1]-(m1:Node)
WITH n, count(DISTINCT m1.type) as typeVariety
WHERE typeVariety > 2
RETURN n.id, n.type, n.degree, typeVariety as connectedTypes
ORDER BY n.degree * typeVariety DESC
LIMIT 20;

// =====================================
// 方法5：使用APOC插件（如果已安装）
// 注意：需要先安装APOC插件

// 5.1 使用APOC的连通分量算法
/*
CALL apoc.algo.community(
    'MATCH (n:Node) RETURN id(n) as id',
    'MATCH (n1:Node)-[r]-(n2:Node) RETURN id(n1) as source, id(n2) as target',
    'OUTGOING'
)
YIELD community, nodes
WITH community, size(nodes) as size
ORDER BY size DESC
LIMIT 1
RETURN community as largestComponentId, size as componentSize;
*/

// =====================================
// 实用查询：直接运行这个来快速了解连通性

// 快速检查：从最高度节点开始的连通分量大小
MATCH (start:Node)
WHERE start.degree = 126  // 最高度节点
CALL {
    WITH start
    MATCH path = (start)-[*..2]-(connected:Node)
    RETURN count(DISTINCT connected) as reachableIn2Steps
}
CALL {
    WITH start
    MATCH path = (start)-[*..3]-(connected:Node)
    RETURN count(DISTINCT connected) as reachableIn3Steps
}
RETURN start.id,
       start.degree,
       reachableIn2Steps,
       reachableIn3Steps;